﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuotationService.RealtimeQuotation
{
    internal class OptionEntityConverter :
        IEntityConverter<Quotation.Option.BasicInfo, OptionBasicInfo>,
        IEntityConverter<Quotation.Option.QuotationInfo, OptionQuotationInfo>,
        IEntityConverter<Quotation.Option.TickInfo, OptionTickInfo>,
        IEntityConverter<Quotation.Option.DailyData, OptionDailyData>,
        IEntityConverter<Quotation.Option.MinuteData, OptionMinuteData>
    {
        public Quotation.Option.BasicInfo Convert(OptionBasicInfo basicInfo)
        {
            return new Quotation.Option.BasicInfo()
            {
                AccountDate = Quotation.Date.FromYMMDD(basicInfo.AccountDate),
                BeginDate = Quotation.Date.FromYMMDD(basicInfo.BeginDate),
                ContractSerialNo = basicInfo.ContractSerialNo,
                ConvertQty = basicInfo.ConvertQty,
                Decimal = basicInfo.Decimal,
                DynamicVer = basicInfo.DynamicVer,
                EndDate = Quotation.Date.FromYMMDD(basicInfo.EndDate),
                MaxLimitOrderQty = basicInfo.MaxLimitOrderQty,
                MaxMarketOrderQty = basicInfo.MaxMarketOrderQty,
                MaxOrderPrice = basicInfo.MaxOrderPrice,
                MinLimitOrderQty = basicInfo.MinLimitOrderQty,
                MinMarketOrderQty = basicInfo.MinMarketOrderQty,
                MinOrderPrice = basicInfo.MinOrderPrice,
                Name = basicInfo.Name,
                OpenPosition = basicInfo.OpenPosition,
                OpenPrice = basicInfo.OpenPrice,
                OrderPriceUnit = basicInfo.OrderPriceUnit,
                PreClosePrice = basicInfo.PreClosePrice,
                PreExchTotalKnockAmt = basicInfo.PreExchTotalKnockAmt,
                PreExchTotalKnockQty = basicInfo.PreExchTotalKnockQty,
                PreOpenPosition = basicInfo.PreOpenPosition,
                PreSettlementPrice = basicInfo.PreSettlementPrice,
                ProductId = basicInfo.ProductId,
                QuotationTime = basicInfo.QuotationTime,
                SettlementPrice = basicInfo.SettlementPrice,
                StaticVer = basicInfo.StaticVer,
                StkId = new Quotation.SymbolCode(basicInfo.Code),
                TradeType = basicInfo.TradeType,
                StkType = basicInfo.StkType,
                UpdateTime = basicInfo.UpdateTime,
                BasicStockId = new Quotation.SymbolCode(basicInfo.BasicStockId),
                ExecPrice = basicInfo.ExecPrice,
                HV = basicInfo.HV,
                OptionCPFlag = basicInfo.OptionCPFlag,
                OptionType = basicInfo.OptionType,
                ContractTimes = basicInfo.ContractTimes
            };
        }

        public OptionBasicInfo Convert(Quotation.Option.BasicInfo basicInfo)
        {
            return new OptionBasicInfo()
            {
                AccountDate = basicInfo.AccountDate.ToYMMDD(),
                BeginDate = basicInfo.BeginDate.ToYMMDD(),
                ContractSerialNo = basicInfo.ContractSerialNo,
                ConvertQty = basicInfo.ConvertQty,
                Decimal = basicInfo.Decimal,
                DynamicVer = basicInfo.DynamicVer,
                EndDate = basicInfo.EndDate.ToYMMDD(),
                MaxLimitOrderQty = basicInfo.MaxLimitOrderQty,
                MaxMarketOrderQty = basicInfo.MaxMarketOrderQty,
                MaxOrderPrice = basicInfo.MaxOrderPrice,
                MinLimitOrderQty = basicInfo.MinLimitOrderQty,
                MinMarketOrderQty = basicInfo.MinMarketOrderQty,
                MinOrderPrice = basicInfo.MinOrderPrice,
                Name = basicInfo.Name,
                OpenPosition = basicInfo.OpenPosition,
                OpenPrice = basicInfo.OpenPrice,
                OrderPriceUnit = basicInfo.OrderPriceUnit,
                PreClosePrice = basicInfo.PreClosePrice,
                PreExchTotalKnockAmt = basicInfo.PreExchTotalKnockAmt,
                PreExchTotalKnockQty = basicInfo.PreExchTotalKnockQty,
                PreOpenPosition = basicInfo.PreOpenPosition,
                PreSettlementPrice = basicInfo.PreSettlementPrice,
                ProductId = basicInfo.ProductId,
                QuotationTime = basicInfo.QuotationTime,
                SettlementPrice = basicInfo.SettlementPrice,
                StaticVer = basicInfo.StaticVer,
                Code = basicInfo.StkId.LongCode,
                TradeType = basicInfo.TradeType,
                StkType = basicInfo.StkType,
                UpdateTime = basicInfo.UpdateTime,
                BasicStockId = basicInfo.BasicStockId.LongCode,
                ExecPrice = basicInfo.ExecPrice,
                HV = basicInfo.HV,
                OptionCPFlag = basicInfo.OptionCPFlag,
                OptionType = basicInfo.OptionType,
                ContractTimes = basicInfo.ContractTimes
            };
        }

        public Quotation.Option.QuotationInfo Convert(OptionQuotationInfo quotInfo)
        {
            var rtn = new Quotation.Option.QuotationInfo()
            {

                StkId = new Quotation.SymbolCode(quotInfo.Code),
                BuyAvgPrice = quotInfo.BuyAvgPrice,
                SellAvgPrice = quotInfo.SellAvgPrice,
                InnerVolume = quotInfo.InnerVolume,
                OuterVolume = quotInfo.OuterVolume,
                NotDefineVolume = quotInfo.NotDefineVolume,
                Name = quotInfo.Name,
                SN = quotInfo.SN,
                UpdateTime = quotInfo.UpdateTime,
                QuotationTime = quotInfo.QuotationTime,
                Tick = Convert(quotInfo.Tick),
                BidAsk = new List<Quotation.BidAsk>()
            };
            if (quotInfo.BidAsk != null)
            {
                foreach (var bidAsk in quotInfo.BidAsk)
                {
                    rtn.BidAsk.Add(new Quotation.BidAsk()
                    {
                        Buy = new Quotation.QtyPrice() { Price = bidAsk.BuyPrice, Qty = bidAsk.BuyQty },
                        Sell = new Quotation.QtyPrice() { Price = bidAsk.SellPrice, Qty = bidAsk.SellQty }
                    });
                }
            }
            return rtn;
        }

        public OptionQuotationInfo Convert(Quotation.Option.QuotationInfo quotInfo)
        {
            var rtn = new OptionQuotationInfo()
            {
                Code = quotInfo.StkId.LongCode,
                ExchId = quotInfo.StkId.ExchId,
                BuyAvgPrice = quotInfo.BuyAvgPrice,
                SellAvgPrice = quotInfo.SellAvgPrice,
                InnerVolume = quotInfo.InnerVolume,
                OuterVolume = quotInfo.OuterVolume,
                NotDefineVolume = quotInfo.NotDefineVolume,
                Name = quotInfo.Name,
                SN = quotInfo.SN,
                UpdateTime = quotInfo.UpdateTime,
                QuotationTime = quotInfo.QuotationTime,
                Tick = Convert(quotInfo.Tick),
                BidAsk = new OrderBook[5]
            };
            if (quotInfo.BidAsk != null)
            {
                int maxIndex = Math.Min(5, quotInfo.BidAsk.Count) - 1;
                for (int i = 0; i < maxIndex; i++)
                {
                    rtn.BidAsk[i] = new OrderBook()
                    {
                        BuyPrice = quotInfo.BidAsk[i].Buy.Price,
                        BuyQty = quotInfo.BidAsk[i].Buy.Qty,
                        SellPrice = quotInfo.BidAsk[i].Sell.Price,
                        SellQty = quotInfo.BidAsk[i].Sell.Qty
                    };
                }
            }
            return rtn;
        }

        public Quotation.Option.TickInfo Convert(OptionTickInfo tickInfo)
        {
            return new Quotation.Option.TickInfo()
            {
                BSType = tickInfo.BSType,
                Diff = tickInfo.Diff,
                DiffRate = tickInfo.DiffRate,
                HighPrice = tickInfo.HighPrice,
                LowPrice = tickInfo.LowPrice,
                OpenPosition = tickInfo.OpenPosition,
                KnockAmt = tickInfo.KnockAmt,
                KnockAvgPrice = tickInfo.KnockAvgPrice,
                KnockPrice = tickInfo.KnockPrice,
                KnockQty = tickInfo.KnockQty,
                KnockTime = Quotation.Time.FromHMMss(tickInfo.KnockTime),
                PositDiff = tickInfo.PositDiff,
                TickSN = tickInfo.TickSN,
                TotalBuyQty = tickInfo.TotalBuyQty,
                TotalBuyQtyDiff = tickInfo.TotalBuyQtyDiff,
                TotalKnockAmt = tickInfo.TotalKnockAmt,
                TotalKnockQty = tickInfo.TotalKnockQty,
                TotalSellQty = tickInfo.TotalSellQty,
                TotalSellQtyDiff = tickInfo.TotalSellQtyDiff,
                VolumeDiff = tickInfo.VolumeDiff,
                VolumeRate = tickInfo.VolumeRate,
                Delta = tickInfo.Delta,
                Gamma = tickInfo.Gamma,
                Rho = tickInfo.Rho,
                TheoreticalPrice = tickInfo.TheoreticalPrice,
                Theta = tickInfo.Theta,
                Vega = tickInfo.Vega,
                IV = tickInfo.IV
            };
        }

        public OptionTickInfo Convert(Quotation.Option.TickInfo tickInfo)
        {
            return new OptionTickInfo()
            {
                BSType = tickInfo.BSType,
                Diff = tickInfo.Diff,
                DiffRate = tickInfo.DiffRate,
                HighPrice = tickInfo.HighPrice,
                LowPrice = tickInfo.LowPrice,
                OpenPosition = tickInfo.OpenPosition,
                KnockAmt = tickInfo.KnockAmt,
                KnockAvgPrice = tickInfo.KnockAvgPrice,
                KnockPrice = tickInfo.KnockPrice,
                KnockQty = tickInfo.KnockQty,
                KnockTime = tickInfo.KnockTime.ToHMMss(),
                PositDiff = tickInfo.PositDiff,
                TickSN = tickInfo.TickSN,
                TotalBuyQty = tickInfo.TotalBuyQty,
                TotalBuyQtyDiff = tickInfo.TotalBuyQtyDiff,
                TotalKnockAmt = tickInfo.TotalKnockAmt,
                TotalKnockQty = tickInfo.TotalKnockQty,
                TotalSellQty = tickInfo.TotalSellQty,
                TotalSellQtyDiff = tickInfo.TotalSellQtyDiff,
                VolumeDiff = tickInfo.VolumeDiff,
                VolumeRate = tickInfo.VolumeRate,
                Delta = tickInfo.Delta,
                Gamma = tickInfo.Gamma,
                Rho = tickInfo.Rho,
                TheoreticalPrice = tickInfo.TheoreticalPrice,
                Theta = tickInfo.Theta,
                Vega = tickInfo.Vega,
                IV = tickInfo.IV
            };
        }

        public Quotation.Option.DailyData Convert(OptionDailyData dailyData)
        {
            return new Quotation.Option.DailyData()
            {
                StkId = new Quotation.SymbolCode(dailyData.Code),
                ClosePrice = dailyData.ClosePrice,
                HighPrice = dailyData.HighPrice,
                LowPrice = dailyData.LowPrice,
                OpenPosition = dailyData.OpenPosition,
                OpenPrice = dailyData.OpenPrice,
                PreSettlementPrice = dailyData.PreSettlementPrice,
                TotalKnockAmt = dailyData.TotalKnockAmt,
                TotalKnockQty = dailyData.TotalKnockQty,
                TradeDay = Quotation.Date.FromYMMDD(dailyData.TradeDay)
            };
        }

        public OptionDailyData Convert(Quotation.Option.DailyData dailyData)
        {
            return new OptionDailyData()
            {
                Code = dailyData.StkId.LongCode,
                ClosePrice = dailyData.ClosePrice,
                HighPrice = dailyData.HighPrice,
                LowPrice = dailyData.LowPrice,
                OpenPosition = dailyData.OpenPosition,
                OpenPrice = dailyData.OpenPrice,
                PreSettlementPrice = dailyData.PreSettlementPrice,
                TotalKnockAmt = dailyData.TotalKnockAmt,
                TotalKnockQty = dailyData.TotalKnockQty,
                TradeDay = dailyData.TradeDay.ToYMMDD()
            };
        }

        public Quotation.Option.MinuteData Convert(OptionMinuteData minuteData)
        {
            return new Quotation.Option.MinuteData()
            {
                ClosePrice = minuteData.ClosePrice,
                StkId = new Quotation.SymbolCode(minuteData.Code),
                HighPrice = minuteData.HighPrice,
                KnockAvgPrice = minuteData.KnockAvgPrice,
                KnockAmt = minuteData.KnockAmt,
                KnockQty = minuteData.KnockQty,
                LowPrice = minuteData.LowPrice,
                OccurTime = Quotation.Time.FromHMM(minuteData.OccurTime),
                OpenPosition = minuteData.OpenPosition,
                OpenPrice = minuteData.OpenPrice,
                TickSN = minuteData.TickSN
            };
        }

        public OptionMinuteData Convert(Quotation.Option.MinuteData minuteData)
        {
            return new OptionMinuteData()
            {
                ClosePrice = minuteData.ClosePrice,
                Code = minuteData.StkId.LongCode,
                HighPrice = minuteData.HighPrice,
                KnockAvgPrice = minuteData.KnockAvgPrice,
                KnockAmt = minuteData.KnockAmt,
                KnockQty = minuteData.KnockQty,
                LowPrice = minuteData.LowPrice,
                OccurTime = (ushort)minuteData.OccurTime.ToHMM(),
                OpenPosition = minuteData.OpenPosition,
                OpenPrice = minuteData.OpenPrice,
                TickSN = minuteData.TickSN
            };
        }


    }
}
